import { initShaders } from '@/lib/webgl'

export default class {
    constructor (el, datas, indices, matrix, lightColor, lightDirection) {
        const styles = window.getComputedStyle(el, null)
        el.width = parseInt(styles.width)
        el.height = parseInt(styles.height)
        const gl = el.getContext('webgl2')
        gl.enable(gl.DEPTH_TEST)

        // 顶点着色器
        const VSHADER_SOURCE = `
            attribute vec4 a_Position;
            attribute vec4 a_Color;
            attribute vec4 a_Normal;
            uniform mat4 u_Matrix;
            uniform vec3 u_LightColor;
            uniform vec3 u_LightDirection;
            varying vec4 v_Color;
            void main() {
                gl_Position = u_Matrix * a_Position;
                vec3 normal = normalize(vec3(a_Normal));
                float nDotL = max(dot(u_LightDirection, normal), 0.0);
                vec3 diffuse = u_LightColor * vec3(a_Color) * nDotL;
                v_Color = vec4(diffuse, a_Color.a);
            }
        `
        const FSHADER_SOURCE = `
            precision mediump float;
            varying vec4 v_Color;
            void main() {
                gl_FragColor = v_Color;
            }
        `
        if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
            console.log('init shader error')
            return
        }
        const initVertexBuffers = (gl) => {
            // 创建缓冲区
            const verticeColorBuffer = gl.createBuffer()
            const indexBuffer = gl.createBuffer()
            if (!verticeColorBuffer || !indexBuffer) {
                return -1
            }

            gl.bindBuffer(gl.ARRAY_BUFFER, verticeColorBuffer)
            gl.bufferData(gl.ARRAY_BUFFER, datas, gl.STATIC_DRAW)
            const eleSize = datas.BYTES_PER_ELEMENT

            const aPosition = gl.getAttribLocation(gl.program, 'a_Position')
            gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 9 * eleSize, 0)
            gl.enableVertexAttribArray(aPosition)

            const aColor = gl.getAttribLocation(gl.program, 'a_Color')
            gl.vertexAttribPointer(aColor, 3, gl.FLOAT, false, 9 * eleSize, 3 * eleSize)
            gl.enableVertexAttribArray(aColor)

            const aNormal = gl.getAttribLocation(gl.program, 'a_Normal')
            gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 9 * eleSize, 6 * eleSize)
            gl.enableVertexAttribArray(aNormal)

            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)
            return indices.length
        }

        // 设置顶点位置
        const n = initVertexBuffers(gl)
        if (n < 0) {
            console.log('initVertexBuffers failed')
            return
        }

        // 设置视图/变换矩阵
        const uMatrix = gl.getUniformLocation(gl.program, 'u_Matrix')
        gl.uniformMatrix4fv(uMatrix, false, matrix)

        // 设置光照颜色
        const uLightColor = gl.getUniformLocation(gl.program, 'u_LightColor') // [1.0, 1.0, 1.0]
        gl.uniform3f(uLightColor, ...lightColor)

        // 设置光线方向
        const uLightDirection = gl.getUniformLocation(gl.program, 'u_LightDirection') // vector3
        gl.uniform3fv(uLightDirection, lightDirection)

        gl.clearColor(0.0, 0.0, 0.0, 1.0)
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
        gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0)

        this.gl = gl
        this.el = el
        this.vertexCount = n
        this.img = el.toDataURL('image/png')
    }
}